package org.fnzn.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.history.HistoricVariableUpdate;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.fnzn.base.impl.BaseServiceImpl;
import org.fnzn.bean.FrontInfoScsp;
import org.fnzn.bean.vo.User;
import org.fnzn.core.Constants;
import org.fnzn.core.ReType;
import org.fnzn.core.Result;
import org.fnzn.enmus.WarrantType;
import org.fnzn.entity.FrontInfoScspVo;
import org.fnzn.entity.ScspOpinionVo;
import org.fnzn.entity.TaskVo;
import org.fnzn.exception.MyException;
import org.fnzn.service.ScspProcessService;
import org.fnzn.util.CommonUtil;
import org.fnzn.util.DicReplace;
import org.fnzn.util.ProcessType;
import org.fnzn.util.ResultGenerator;
import org.fnzn.util.SpResultType;

import java.util.*;
@Service
public class ScspProcessServiceImpl extends BaseServiceImpl<FrontInfoScsp,String> implements ScspProcessService {
	@Autowired
	private ScspProcessService scspProcessService;	
	@Autowired
	private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;    
    @Autowired
    private HistoryService historyService;
    
//    @Autowired
//    private GuarantorService guarantorService;
//    @Autowired
//	private CreditService creditService;
//    @Autowired
//   	private ScspService scspService;
//    @Autowired
//    private SurveyMortgageService surveyMortgageService;
//    @Autowired
//    private SurveyPledgeService surveyPledgeService;
    

    private  String scspOpinionList="scspOpinionList";
    
	@Override
	public ReType findList(FrontInfoScsp scsp, String page, String limit) {
	  List<FrontInfoScsp> tList=null;
      List<FrontInfoScspVo> tVoList=new ArrayList<FrontInfoScspVo>();
      Page<FrontInfoScsp> tPage= PageHelper.startPage(Integer.valueOf(page),Integer.valueOf(limit),true);     
      tList=scspProcessService.selectList(scsp);  
     
      Map<String, String> dicMap = new HashMap<String, String>();
      dicMap.put("warrant", "WARRANT");
      dicMap.put("serviceBreed", "SERVICE_BREED");
      for(FrontInfoScsp scspInfo:tList){
    	FrontInfoScspVo scspVo=new FrontInfoScspVo();
    	BeanUtils.copyProperties(scspInfo, scspVo);
    	if(StringUtils.isNotBlank(scspInfo.getWarrant())){
    		String[] warrants=scspInfo.getWarrant().split(",");
        	scspVo.setWarrants(warrants);
    	} 	
    	if(StringUtils.isNotBlank(scspInfo.getProcessId())){
    		/*ProcessInstance instance= runtimeService.createProcessInstanceQuery()
    	            .processInstanceId(scspInfo.getProcessId()).singleResult();
	        //保证运行ing
	        if(instance!=null){
	          Task task = this.taskService.createTaskQuery().processInstanceId(scspInfo.getProcessId()).singleResult();
	          scspVo.setTaskName(task.getName());
	        }*/
    		//获取当前状态
    		/*String taskName=getTaskName(scspInfo.getProcessId());
    		if(StringUtils.isNotBlank(taskName)){
    			scspVo.setTaskName(taskName);
    		}*/
    	}     
        //字典名称转化
        DicReplace.replaceDics(scspVo, dicMap);
        DicReplace.replaceChildDic(scspVo, "serviceBreed", "serviceBreed2");
        tVoList.add(scspVo);
        
      }     
      return new ReType(tPage.getTotal(),tVoList);
	}

	@Override
	@Transactional
	public Result addScsp(FrontInfoScspVo voScsp) {
		User user=CommonUtil.getUser();
		if(voScsp==null||StringUtils.isBlank(voScsp.getScspId())||StringUtils.isBlank(voScsp.getIdNo())){
    		return ResultGenerator.genFailResult("获取数据失败");
    	}
    	FrontInfoScsp scspInfo=scspProcessService.selectByPrimaryKey(voScsp.getScspId());
    	if(addScspCheck(scspInfo)){
	    	Map<String,Object> map=new HashMap<String,Object>();
	        map.put("scsp",voScsp);
	        map.put("type", ProcessType.SCSP_PROCESS);
	        map.put("idNo", voScsp.getIdNo());
	        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("scsp_process_"+user.getCorpCD(),map);
	        if (processInstance == null) {
	        	return ResultGenerator.genFailResult("未识别key");
	        }
	        voScsp.setProcessId(processInstance.getId());
	        voScsp.setProcessState(Constants.STATLCZ);
	        BeanUtils.copyProperties(voScsp, scspInfo);
	        scspProcessService.updateByPrimaryKeySelective(scspInfo);
    	}
    	return ResultGenerator.genSuccessResult("申批流程提交成功");
		
	}
	@Override
	@Transactional
	public void deleteScsp(String scspId){
		FrontInfoScsp scsp = selectByPrimaryKey(scspId);
		if(StringUtils.isBlank(scspId)){
			throw new MyException("参数错误");
		}
		runtimeService.deleteProcessInstance(scsp.getProcessId(),"客户经理取消流程");
		//scspService.deleteScsp(scspId);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ScspOpinionVo> findOptionList(String processId) {
		//获取流程实例
		ProcessInstance instance= runtimeService.createProcessInstanceQuery()
		          .processInstanceId(processId).singleResult();
        //保证运行ing
        List<ScspOpinionVo> optionList=new ArrayList<>();
        if(instance!=null){
          List<Task> tasks = this.taskService.createTaskQuery().processInstanceId(processId).orderByTaskCreateTime().desc().list();;
          Task task=tasks.get(0);
          Map<String, Object> variables = taskService.getVariables(task.getId());
          Object o = variables.get(scspOpinionList);
          if(o!=null){
            /*获取历史审核信息*/
            optionList= ( List<ScspOpinionVo>) o;
          }
        }else{
            List<HistoricDetail> list = historyService.createHistoricDetailQuery().
                  processInstanceId(processId).list();
            HistoricVariableUpdate variable=null;
            for(HistoricDetail historicDetail:list){
              variable= (HistoricVariableUpdate) historicDetail;
              String variableName = variable.getVariableName();
              if(scspOpinionList.equals(variableName)){
            	  optionList.clear();
            	  optionList.addAll((List<ScspOpinionVo>)variable.getValue());
              }
            }
        }
		return optionList;
	}

	@Override
	public ReType showTaskList(TaskVo task, String page, String limit) {
		User user = CommonUtil.getUser();
		//创建任务查询
		TaskQuery qury=taskService.createTaskQuery()
				  .taskCandidateOrAssigned(user.getUser_id())
	    		  .processVariableValueEquals("type", ProcessType.SCSP_PROCESS);
		//查询条件
		if(StringUtils.isNotBlank(task.getIdNo())){
			qury.processVariableValueEquals("idNo", task.getIdNo());
		}
		List<Task> taskList=qury.orderByTaskCreateTime().desc()
		  .listPage(Integer.valueOf(limit) * (Integer.valueOf(page) - 1), Integer.valueOf(limit));
		
	    List<TaskVo> tasks=new ArrayList<TaskVo>();
	    Map<String,Object> map=new HashMap<>();
	    TaskVo taskEntity=null;	 
	    for(Task task1:taskList){
	      map=taskService.getVariables(task1.getId());
	      FrontInfoScspVo scsp= (FrontInfoScspVo) map.get("scsp");
	      if(StringUtils.isNotBlank(scsp.getWarrant())){
	    	String[] warrants=scsp.getWarrant().split(",");
	    	scsp.setWarrants(warrants);
	      } 
	      taskEntity=new TaskVo(task1);
	      BeanUtils.copyProperties(scsp, taskEntity);
	      /**如果是自己*/
	      if(user.getUser_id().equals(scsp.getCustGrpJl())){
        	taskEntity.setSelfFlag(true);
	      }else{
        	taskEntity.setSelfFlag(false);
	      }
	      tasks.add(taskEntity);
	    }
		return new ReType(taskList.size(),tasks);
	}
	/**
	 * 完成任务
	 */
	@SuppressWarnings("unchecked")
	@Override
	@Transactional
	public String complete(ScspOpinionVo op) {
		Task task=taskService.createTaskQuery().taskId(op.getTaskId()).singleResult();
		Map<String, Object> variables = taskService.getVariables(op.getTaskId());
		FrontInfoScspVo scspVo= (FrontInfoScspVo) variables.get("scsp");
		FrontInfoScsp scsp=scspProcessService.selectByPrimaryKey(scspVo.getScspId());
		Map<String,Object> map=new HashMap<>();
		User user = CommonUtil.getUser();
		if(scspVo.getCustGrpJl().equals(user.getUser_id())){//客户经理完成任务默认审批意见
			if(task.getName().equals("客户经理确认")){
				completeScspCheck(scsp);//客户经理确认时检查补录信息
			}
			if(op.getFlag().equals(SpResultType.AGREE.getCode())){
				op.setOpinion("通过");
			}else{
				op.setOpinion("撤销");
			}
			
		}
		if(task.getName().equals("贷审会会审")){//贷审会流程变量控制
			int passCount=(int) variables.get("passCount");
			int noAgreeCount=(int) variables.get("noAgreeCount");
			if(op.getFlag().equals(SpResultType.AGREE.getCode())){
				passCount++;
				map.put("passCount", passCount);
			}else if(op.getFlag().equals(SpResultType.NO_AGREE.getCode())){
				noAgreeCount++;
				map.put("noAgreeCount", noAgreeCount);
			}			
		}else{
			taskService.claim(op.getTaskId(), user.getUser_id());//认领任务
		}
		
		op.setScspId(scspVo.getScspId());
		op.setCreTime(new Date());
		op.setOpId(user.getUser_id());
		op.setOpName(user.getUserName());
		op.setProcessInstancesId(scspVo.getProcessId());
		
		map.put("flag",op.getFlag());
		if("F".equals(op.getFlag())){
			map.put("opinion",op.getOpinion());
		}
		//审批信息叠加
		List<ScspOpinionVo> scspOptionList=new ArrayList<>();
		Object o = variables.get("scspOpinionList");
		if(o!=null){
    	  scspOptionList= (List<ScspOpinionVo>) o;
		}
		scspOptionList.add(op);
		map.put("scspOpinionList",scspOptionList);
		String processId = scsp.getProcessId();
		//taskService.addComment(op.getTaskId(), processId, op.getOpinion()==null?"通过":op.getOpinion());
		taskService.complete(op.getTaskId(),map);
		//return getTaskName(processId);
		return null;
	}
	/**
	 * 提交申请审批流程时检查信息是否完整
	 * @param scspInfo
	 * @return
	 */
	private boolean addScspCheck(FrontInfoScsp scspInfo){
		boolean flag=true;
		String scspId=scspInfo.getScspId();
		String warrant=scspInfo.getWarrant();
		if(StringUtils.isBlank(warrant)){
			throw new MyException("担保方式不能为空");
		}
		/*if(warrant.contains(WarrantType.BZ.getCode())){
			List<FrontInfoGuarantor>  guList=guarantorService.findList(scspId);
			if(guList.isEmpty()){
				throw new MyException("担保方式为保证,没有添加保证人信息");
			}else{
				for(FrontInfoGuarantor guarantor:guList){
					if(guarantor.getGuarantorAmount()==null){
						throw new MyException("请完善保证人【"+guarantor.getName()+"】的信息");
					}
				}
			}			
		}
		if(warrant.contains(WarrantType.DY.getCode())){
			List<FrontInfoSurveyMortgage> moList=surveyMortgageService.findByScspId(scspId);
			if(moList.isEmpty()){
				throw new MyException("担保方式为抵押,没有添加抵押信息");
			}			
		}
		if(warrant.contains(WarrantType.ZY.getCode())){
			List<FrontInfoSurveyPledge>  plList=surveyPledgeService.findByScspId(scspId);
			if(plList.isEmpty()){
				throw new MyException("担保方式为质押,没有添加质押信息");
			}		
		}	
		if(StringUtils.isEmpty(scspInfo.getSurveyState())){
    		throw new MyException("请先完成调查报告");
    	}  
		if(StringUtils.isEmpty(scspInfo.getCreditState())){
    		throw new MyException("请先完成合同信息");
    	}*/
			
    	return flag;
	}
	/**
	 * 客户经理确认时检查信息是否完整
	 * @param scspInfo
	 * @return
	 */
	private boolean completeScspCheck(FrontInfoScsp scspInfo) {
		boolean flag = true;
		String scspId = scspInfo.getScspId();
		String warrant = scspInfo.getWarrant();
		if (StringUtils.isBlank(warrant)) {
			throw new MyException("担保方式不能为空");
		}
		if (warrant.contains(WarrantType.DY.getCode())) {
		/*	List<FrontInfoSurveyMortgage> moList=surveyMortgageService.findByScspId(scspId);
			if(moList.isEmpty()){
				throw new MyException("担保方式为抵押,没有添加抵押信息");
			}else{		
				for(FrontInfoSurveyMortgage mortgage:moList){
					if(StringUtils.isBlank(mortgage.getDyqsr())){
						throw new MyException("抵押合同【"+mortgage.getMortgageNo()+"】抵押起始日为空，请补充完整");
					}else if(StringUtils.isBlank(mortgage.getDyzzr())){
						throw new MyException("抵押合同【"+mortgage.getMortgageNo()+"】抵押终止日为空，请补充完整");
					}else if(StringUtils.isBlank(mortgage.getQzbh())){
						throw new MyException("抵押合同【"+mortgage.getMortgageNo()+"】权证编号为空，请补充完整");
					}else if(StringUtils.isBlank(mortgage.getPgdw())){
						throw new MyException("抵押合同【"+mortgage.getMortgageNo()+"】评估单位为空，请补充完整");
					}else if(StringUtils.isBlank(mortgage.getPgsj())){
						throw new MyException("抵押合同【"+mortgage.getMortgageNo()+"】评估日期为空，请补充完整");
					}else if(StringUtils.isBlank(mortgage.getDyjg())){
						throw new MyException("抵押合同【"+mortgage.getMortgageNo()+"】抵押机关为空，请补充完整");
					}				
				}
			}			
		}
		if(warrant.contains(WarrantType.ZY.getCode())){
			List<FrontInfoSurveyPledge>  plList=surveyPledgeService.findByScspId(scspId);
			if(plList.isEmpty()){
				throw new MyException("担保方式为质押,没有添加质押信息");
			}else{
				for(FrontInfoSurveyPledge pledge:plList){
					if(StringUtils.isBlank(pledge.getZyqsr())){
						throw new MyException("质押合同【"+pledge.getPledgeNo()+"】质押起始日为空，请补充完整");
					}else if(StringUtils.isBlank(pledge.getZyzzr())){
						throw new MyException("质押合同【"+pledge.getPledgeNo()+"】质押终止日为空，请补充完整");
					}
				}
			}		
		}	 
		if(StringUtils.isEmpty(scspInfo.getCreditState())){
    		throw new MyException("请先完成合同信息");
    	}else{
    		FrontInfoCredit credit = creditService.findById(scspInfo.getScspId());
    		if(StringUtils.isBlank(credit.getStartDate())){
    			throw new MyException("合同信息放款日期为空，请补充完整");
    		}else if(StringUtils.isBlank(credit.getGrantAccount())){
    			throw new MyException("合同信息放款账户为空，请补充完整");
    		}else if(StringUtils.isBlank(credit.getRepaymentAccount())){
    			throw new MyException("合同信息还款账户为空，请补充完整");
    		}
    	}
			
    	return flag;
	}
	public String getTaskName(String processId) {
		String taskName=null;
		ProcessInstance instance= runtimeService.createProcessInstanceQuery()
	            .processInstanceId(processId).singleResult();
        //保证运行ing
        if(instance!=null){
          //Task task = this.taskService.createTaskQuery().processInstanceId(processId).singleResult();
          List<Task> tasks=taskService.createTaskQuery().processInstanceId(processId).list();//并行时存在多条记录
          for(Task task:tasks){
        	  if(taskName==null){
        		  taskName=task.getName();
        	  }else{
        		  if(!taskName.contains(task.getName())){
        		  	taskName+=" "+task.getName();
        	  	  }
        	  }
          }	       
        }*/
			//  return taskName;
		}
		return false;
	}

}
